package com.jrx.anytxn.reporting.job.xib.step;

import com.jrx.anytxn.common.constant.Constants;
import com.jrx.anytxn.common.data.TxnRespCode;
import com.jrx.anytxn.common.exception.TxnBizException;
import com.jrx.anytxn.common.uitl.DateUtils;
import com.jrx.anytxn.customer.constant.CustomerConstant;
import com.jrx.anytxn.customer.entity.CmCustomerExtInfo;
import com.jrx.anytxn.customer.entity.CmCustomerFirstLevel;
import com.jrx.anytxn.customer.entity.CmCustomerLimitInfo;
import com.jrx.anytxn.customer.entity.CmCustomerSecondLevel;
import com.jrx.anytxn.customer.entity.CmLimitAdjustLog;
import com.jrx.anytxn.customer.mapper.ext.ExtCmCustomerExtInfoMapper;
import com.jrx.anytxn.customer.mapper.ext.ExtCmCustomerLimitInfoMapper;
import com.jrx.anytxn.customer.service.ICustomerLimitInfoService;
import com.jrx.anytxn.customer.service.ICustomerService;
import com.jrx.anytxn.param.entity.PrCreditLimitMapping;
import com.jrx.anytxn.param.entity.PrOrganizationTable;
import com.jrx.anytxn.param.mapper.ext.ExtPrCreditLimitMappingMapper;
import com.jrx.anytxn.param.service.system.IOrganizationTableService;
import com.jrx.anytxn.param.utils.BizTypeProducts;
import com.jrx.anytxn.reporting.constant.ReportingConstant;
import com.jrx.anytxn.reporting.entity.CmInteCoLonCrdtInfo;
import com.jrx.anytxn.reporting.entity.CoLonCrdtInfoBean;
import com.jrx.anytxn.reporting.entity.LimitChangeLogUpdate;
import com.jrx.anytxn.transaction.constant.TransBizConstant;
import com.jrx.anytxn.transaction.entity.AmLoanAccountInfo;
import com.jrx.anytxn.transaction.entity.AmRepaymentPlanInfo;
import com.jrx.anytxn.transaction.mapper.ext.ExtAmLoanAccountInfoMapper;
import com.jrx.anytxn.transaction.mapper.ext.ExtAmRepaymentPlanInfoMapper;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * @description: 贷款授信信息Processor 数据处理入口  (兴安借)
 * @author: shigongtai
 * @date: 2023/4/13 14:29
 */
@Service
public class CreditInfoXajReportingProcessor implements ItemProcessor<CmCustomerFirstLevel, CoLonCrdtInfoBean> {

    @Autowired
    private IOrganizationTableService organizationTableService;
    @Resource
    ICustomerLimitInfoService iCustomerLimitInfoService;
    @Resource
    ExtAmRepaymentPlanInfoMapper extAmRepaymentPlanInfoMapper;
    @Resource
    ExtPrCreditLimitMappingMapper extPrCreditLimitMappingMapper;
    @Resource
    ExtCmCustomerLimitInfoMapper extCmCustomerLimitInfoMapper;
    @Resource
    private ExtAmLoanAccountInfoMapper extAmLoanAccountInfoMapper;
    @Resource
    private ExtCmCustomerExtInfoMapper extCmCustomerExtInfoMapper;
    @Autowired
    ICustomerService iCustomerService;

    private static final Logger logger = LoggerFactory.getLogger(CreditInfoXajReportingProcessor.class);

    @Override
    public CoLonCrdtInfoBean process(CmCustomerFirstLevel cust) throws Exception {
        try {
            if (cust == null) { return null; }

            if (StringUtils.isEmpty(cust.getEcifId())) {
                return null;
            }
            CoLonCrdtInfoBean bean = new CoLonCrdtInfoBean();
            PrOrganizationTable org = organizationTableService.findByOrgIdForBatch(ReportingConstant.DEFAULT_ORG_NUMBER);
            Date today = org.getToday();
            String customerId = cust.getCustomerId();
            String tenantId = cust.getTenantId();
            List<String> xajSeriesProducts = BizTypeProducts.getXAJSeriesProducts();
            // 查询激活的产品ids
            List<String> activeProducts = extCmCustomerExtInfoMapper.getActiveProducts(customerId, tenantId, Arrays.asList("1", "2"), xajSeriesProducts);
            if(CollectionUtils.isEmpty(activeProducts)) {
                return null;
            }
            //获取客户相关的所有额度编号，做集合运算  兴安花系列产品对应的额度列表
            List<String> limitIds = extPrCreditLimitMappingMapper.selectLimitIdByTenIdAndProductIds(tenantId, activeProducts);
            if (limitIds.isEmpty()) {
                return null;
            }
            PrCreditLimitMapping prCreditLimitMapping = extPrCreditLimitMappingMapper.selectByTenIdAndProIdAndChannel(cust.getTenantId(), TransBizConstant.DEFAULT_CHANNEL_NO, BizTypeProducts.XAJ_PRODUCT);
            if (null == prCreditLimitMapping) {
                String message = MessageFormat.format("根据tenantId:{0},channel:{1},productId:{2},未找到对应的limitMapping", cust.getTenantId(), TransBizConstant.DEFAULT_CHANNEL_NO, BizTypeProducts.XAJ_PRODUCT);
                throw new TxnBizException(TxnRespCode.NO_DATA.getCode(), message);
            }

            //兴安借不会有多个
            CmCustomerLimitInfo limitInfo = extCmCustomerLimitInfoMapper.selectByTenIdAndCusIdAndLimitId(cust.getTenantId(), cust.getCustomerId(), prCreditLimitMapping.getLimitId());
            if (limitInfo == null || "".equals(limitInfo.getSeqNo())){
                return null;
            }

            CmInteCoLonCrdtInfo lon = new CmInteCoLonCrdtInfo();
            //租户id
            lon.setTenantId(tenantId);
            //数据日期
            lon.setEtlDt(today);
            //法人机构标识
            lon.setLpOrgNo("XIB");
            //核心客户编号
            lon.setCoreCustNo(cust.getEcifId());
            //txn客户编号
            lon.setCustNo(customerId);
            //来源平台编号
            lon.setSrcPlatNo("CCS");
            List<CmCustomerLimitInfo> infosOrderBytLimitEffectiveDate = iCustomerLimitInfoService.getCmCustomerLimitInfos(customerId, tenantId, cust.getOrganizationId(),
                    limitIds);
            if (CollectionUtils.isEmpty(infosOrderBytLimitEffectiveDate)) {
                return null;
            }
            if (CollectionUtils.isNotEmpty(infosOrderBytLimitEffectiveDate)) {
                //总授信额度
                BigDecimal xahSeriesTotalLimitAmount = infosOrderBytLimitEffectiveDate.stream().map(CmCustomerLimitInfo::getLimitAmount)
                        .filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
                //总已使用额度
                BigDecimal xahSeriesTotalUsedLimitAmount = infosOrderBytLimitEffectiveDate.stream().map(CmCustomerLimitInfo::getLimitUsed)
                        .filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
                //当前生效额度
                lon.setCurrEffectLmt(xahSeriesTotalLimitAmount);
                //已使用额度
                lon.setUsedLmt(xahSeriesTotalUsedLimitAmount);
                //供数首笔信息
                CmCustomerLimitInfo first = infosOrderBytLimitEffectiveDate.get(0);
                //额度类型代码
                lon.setLmtTypeCd("4");
                //是否循环额度，0-循环，1-非循环
                lon.setIsRecycled(first.getUseMode());
                //额度编号
                lon.setLmtNo(limitInfo.getLimitId());
                //授信合同编号
                lon.setCrdtContNo(limitInfo.getContractNumber());
                //当前额度生效日期
                Date etlEffectiveDate = limitInfo.getLimitEffectiveDate();
                lon.setCurrLmtEffectDt(etlEffectiveDate);
                Date etlExpiryDate = limitInfo.getLimitExpiryDate();
                // 当前额度失效日期
                lon.setInvalidDt(etlExpiryDate);
                // 额度到期当天
                Date expiryDate = DateUtils.addDay(etlExpiryDate, 1);
                // 只有   用户没有逾期&&额度到期当天   才能修改额度有效期
                if (today.compareTo(expiryDate) == 0 && StringUtils.isBlank(cust.getBlockCode()) ) {
                    // 查询最后的还款日期
                    // 查询还款计划
                    List<AmRepaymentPlanInfo> planList = extAmRepaymentPlanInfoMapper.queryPlanInfo(tenantId, first.getChannel(), customerId,
                            Arrays.asList(TransBizConstant.LOAN_PLAN_STATUS_0, TransBizConstant.LOAN_PLAN_STATUS_1), xajSeriesProducts);
                    if (CollectionUtils.isNotEmpty(planList)) {
                        Optional<AmRepaymentPlanInfo> max = planList.stream().max(Comparator.comparing(AmRepaymentPlanInfo::getPaymentDueDate));
                        // 存在且最后的还款日比现在的时间大
                        if (max.isPresent()) {
                            Date paymentDueDate = max.get().getPaymentDueDate();
                            if (paymentDueDate.compareTo(today) >= 0) {
                                lon.setInvalidDt(paymentDueDate);
                                LimitChangeLogUpdate updateLimitChangeLog = new LimitChangeLogUpdate();
                                updateLimitChangeLog.setTenantId(tenantId);
                                updateLimitChangeLog.setEtlExpiryDate(paymentDueDate);
                                updateLimitChangeLog.setCustomerId(customerId);
                                updateLimitChangeLog.setEtlContractNumber(limitInfo.getContractNumber());
                                updateLimitChangeLog.setEtlLimitId(limitInfo.getLimitId());
                                bean.setUpdateLimitChangeLog(updateLimitChangeLog);
                            }
                        }
                    }
                }

                //统计客户订单查询
                AmLoanAccountInfo countAcct = extAmLoanAccountInfoMapper.selectMaxLoanWithProducts(customerId, tenantId, xajSeriesProducts, etlEffectiveDate);

                // 未用信的的用户 结清日期等于额度失效日期
                if (today.compareTo(etlExpiryDate) >= 0 && Objects.isNull(countAcct)) {
                    LimitChangeLogUpdate updateLimitChangeLog = bean.getUpdateLimitChangeLog();
                    if (Objects.isNull(updateLimitChangeLog)) {
                        updateLimitChangeLog = new LimitChangeLogUpdate();
                        updateLimitChangeLog.setTenantId(tenantId);
                        updateLimitChangeLog.setCustomerId(customerId);
                        updateLimitChangeLog.setEtlLimitId(limitInfo.getLimitId());
                        updateLimitChangeLog.setEtlContractNumber(limitInfo.getContractNumber());
                    }
                    updateLimitChangeLog.setEtlSettleDate(etlExpiryDate);
                    bean.setUpdateLimitChangeLog(updateLimitChangeLog);
                }
                // 查询用户首次额度
                CmLimitAdjustLog firstAdjustLog = iCustomerLimitInfoService.queryFirstAdjustLog(tenantId, customerId, limitIds, CustomerConstant.SUCCESS, etlEffectiveDate);
                if (Objects.nonNull(firstAdjustLog)) {
                    // 首次额度生效日期
                    lon.setFirstLmtEffectDt(firstAdjustLog.getBusinessDate());
                    // 首次生效额度
                    lon.setFirstEffectLmt(firstAdjustLog.getLimitPermBefore());
                }else {
                    logger.info("没有查询到首次额度生效日期，客户id:{},机构id:{}", tenantId, customerId);
                }
            }

            //获取2级客户信息
            CmCustomerSecondLevel secondLevel = iCustomerService.getSecondByChannelAndCustomerIdAndTensnId( TransBizConstant.DEFAULT_CHANNEL_NO, customerId, tenantId, BizTypeProducts.XAJ_PRODUCT);
            //所属机构编号
            lon.setBelongOrgNo(secondLevel.getBankOrgNo());
            //考核机构编号
            lon.setAssesOrgNo(secondLevel.getBankOrgNo());
            // 所属机构名称
            lon.setBelongOrgName("");
            // 考核机构名称
            lon.setAssesOrgName("");
            bean.setCrdtInfo(lon);
            return bean;
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("CreditInfoXajReportingProcessor出错了：{}", e.getMessage());
        }
        return null;
    }


    /**
     * 根据条件查询客户扩展信息表
     *
     * @param channel
     * @param tenantId
     * @param CustomerId
     * @param productId
     */
    private CmCustomerExtInfo getUserExtendInfoConditions(String channel,String tenantId,String CustomerId,String productId) {
        // 根据条件查询客户扩展信息表
        CmCustomerExtInfo info = new CmCustomerExtInfo();
        info.setChannel(channel);
        info.setTenantId(tenantId);
        info.setCustomerId(CustomerId);
        info.setProductId(productId);
        CmCustomerExtInfo res = extCmCustomerExtInfoMapper.selectByConditions(info);
        return res;
    }

}
